package admin

import (
	"fmt"
	"mycms/global"
	"mycms/model/system"
	systemReq "mycms/model/system/request"
	systemRes "mycms/model/system/response"
)

//	获取用户动态路由
func GetUserMenus(parentId uint) (menu []systemRes.UserMenuResponse) {

	db := global.DB.Model(&system.Menu{})
	var menuList []system.Menu
	err := db.Where("status = ? AND parent_id = ? AND menu_type = ?", 1, parentId, 1).Order("sort desc").Find(&menuList).Error

	if err != nil{
		return
	}
	if len(menuList) > 0 {
		for _, val := range menuList{
			var Children []systemRes.UserMenuResponse

			//	处理Vue页面路径
			if val.Component == ""{
				val.Component = "Layout"
			}

			//	顶级加"/"
			if val.ParentId == 0{
				val.Path = "/"+val.Path
			}

			//	是否显示
			show := true
			if val.AlwaysShow == 0{
				show = false
			}

			//	递归获取子级菜单
			Children = GetUserMenus(val.ID)

			//	前端在面包屑中点击会重定向去的地址，我们不用，所以设置为布尔值
			redirect := true
			if len(Children) == 0{
				redirect = false
			}

			//	查询菜单所属角色
			var Roles []uint
			global.DB.Model(&system.RoleMenu{}).Where("menu_id = ?", val.ID).Select([]string{"role_id"}).Scan(&Roles)

			//	角色ID为0表示超级管理员，所有菜单加这个权限
			Roles = append(Roles, 0)

			//	组装数据
			menu = append(menu, systemRes.UserMenuResponse{
				Path: val.Path,
				Name: val.Name,
				Component: val.Component,
				AlwaysShow: show,
				Redirect: redirect,
				Children: Children,
				Meta: systemRes.Meta{
					Title: val.Title,
					Icon: val.Icon,
					Roles: Roles,
				},
			})
		}
	}

	return menu
}

//	后台菜单列表树
func GetMenuTree(parentId uint) (menu []systemRes.MenuListResponse) {

	var menuList []system.Menu
	db := global.DB.Model(&system.Menu{})

	//	查询
	err := db.Where("parent_id = ?", parentId).Order("sort desc").Find(&menuList).Error

	if err != nil{
		return
	}

	if len(menuList) > 0 {

		var Children []systemRes.MenuListResponse
		for _, val := range menuList{
			//	递归获取子级菜单
			Children = GetMenuTree(val.ID)

			menu = append(menu, systemRes.MenuListResponse{
				Id: val.ID,
				ParentId: val.ParentId,
				Path: val.Path,
				Icon: val.Icon,
				Title: val.Title,
				Component: val.Component,
				Name: val.Name,
				Status: val.Status,
				MenuType: val.MenuType,
				Children: Children,
			})


		}
	}
	return menu
}

//	后台菜单详情
func GetMenuInfo(param systemReq.MenuInfoParams) (err error, menuInfo system.Menu) {

	db := global.DB.Model(&system.Menu{})
	err = db.Where("id = ?", param.Id).First(&menuInfo).Error

	return err, menuInfo

}


//	更新后台菜单
func UpdateMenu(param systemReq.UpdateMenuParams) (err error) {
	tx := global.DB.Begin()

	//	延时回调
	defer func() {
		if r := recover(); r != nil {
			//	事务回滚
			tx.Rollback()
		}
	}()

	//	事务开启失败时返回错误
	if err := tx.Error; err != nil {
		return err
	}


	var menu system.Menu
	var menu_apis system.MenuApis
	err = tx.Where("id = ?", param.Id).First(&menu).Error

	if err == nil {
		fmt.Printf("%+v", param)
		//	Select("*")更新所有字段
		err = tx.Model(menu).Select("Title","Name","ParentId","Path","Status","Sort","AlwaysShow","Icon","Component","MenuType").Updates(system.Menu{
			Title: param.Title,
			Name: param.Name,
			ParentId: param.ParentId,
			Path: param.Path,
			Status: param.Status,
			Sort: param.Sort,
			AlwaysShow: param.AlwaysShow,
			Icon: param.Icon,
			Component: param.Component,
			MenuType: param.MenuType,
		}).Error

		if err != nil {
			tx.Rollback()
			return err
		}

		//	TODO 更新关联表
		if err = tx.Where("menu_id = ?", param.Id).Delete(&menu_apis).Error; err != nil{
			tx.Rollback()
			return err
		}

		var createData []system.MenuApis

		for _, v := range param.ApiId{
			createData = append(createData, system.MenuApis{
				MenuId: param.Id,
				ApiId: v,
			})
		}

		if len(createData) > 0{

			if err = tx.Create(&createData).Error; err != nil{
				tx.Rollback()
				return err
			}
		}

		//	TODO 更新拥有这个菜单的角色对应的权限
		var roleMenuList []system.RoleMenu

		err := tx.Where("menu_id = ?", param.Id).Find(&roleMenuList).Error
		fmt.Printf("%v", roleMenuList)
		if err != nil{
			tx.Rollback()
			return err
		}

		for _, val := range roleMenuList{
			err = UpdateRoleRule(int(val.RoleId))
			if err != nil{
				tx.Rollback()
				return err
			}
		}

	}else{
		tx.Rollback()
		return err
	}

	//	事务提交
	return tx.Commit().Error
}

//	新增后台菜单
func CreateMenu(menu system.Menu, apis []uint) (err error) {

	tx := global.DB.Begin()

	//	延时回调
	defer func() {
		if r := recover(); r != nil {
			//	事务回滚
			tx.Rollback()
		}
	}()

	//	事务开启失败时返回错误
	if err := tx.Error; err != nil {
		return err
	}

	err = tx.Create(&menu).Error

	//	TODO 更新关联表
	var menu_apis system.MenuApis
	if err = tx.Where("menu_id = ?", menu.ID).Delete(&menu_apis).Error; err != nil{
		tx.Rollback()
		return err
	}

	var createData []system.MenuApis

	for _, v := range apis{
		createData = append(createData, system.MenuApis{
			MenuId: menu.ID,
			ApiId: v,
		})
	}

	if len(createData) > 0{

		if err = tx.Create(&createData).Error; err != nil{
			tx.Rollback()
			return err
		}
	}

	//	事务提交
	return tx.Commit().Error
}

//	删除后台菜单
func DelMenu(param systemReq.MenuDelParams) (err error) {
	var menu system.Menu
	err = global.DB.Where("id = ?", param.Id).Delete(&menu).Error
	return err
}
